/*
面向对象：1.找对象 ， 2.调用对象的方法和属性实现效果
   把每个小球当成一个对象 ， 把生成小球和让小球能够动起来的等等代码都封装起来

       封装：
           属性
               半径,颜色,速度,位置
               radius,color,vx,vy,x,y
           方法
               draw(),move()
*/
class Ball {

    /**
     * 球的class的构造函数
     * @param { Number } x  圆心的x坐标
     * @param { Number } y  圆心的y坐标
     * @param { Number } vx x轴方向的速度
     * @param { Number } vy y轴方向的速度
     * @param { Number } radius 圆的半径 
     * @param { String } color 球的颜色 
     */
    constructor(x, y, vx, vy, radius, color) {
        this.x = x
        this.y = y
        this.vx = vx
        this.vy = vy
        this.radius = radius
        this.color = color
    }
    // context作为参数传入，好处是，我们将来如果把代码拿走，也可以正常使用
    draw(context) {
        context.beginPath()
        context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI)
        context.closePath()
        context.fillStyle = this.color
        context.fill()
    }
    // 包含移动和回弹的代码
    move() {
        this.x += this.vx
        this.y += this.vy
        // 判断 到达了边缘没有
        if (this.x <= +this.radius || this.x >= (800 - this.radius)) {
            this.vx *= -1
        }
        if (this.y <= +this.radius || this.y >= (600 - this.radius)) {
            this.vy *= -1
        }
    }
    // 判断是否和别的小球发生了碰撞的方法 , 通过返回true或者false来知道是否和别的小球发生了碰撞
    isCollision(other) { // other是另一个小球
        const dx = this.x - other.x;
        const dy = this.y - other.y;
        const distance = Math.sqrt(dx * dx + dy * dy);
        // 如果 两个圆心之间的距离，小于两个球半径和，就是碰撞了
        if (distance < this.radius + other.radius) {
            return true
        }
        return false
    }
}

/**
 * 随机整数
 * @param { Number } min 随机数最小值 
 * @param { Number } max 随机数最大值
 * @returns Number
 */
function random(min, max) {
    return Math.floor(Math.random() * (max - min)) + min;
}

/**
 * 随机颜色
 * @returns String
 */
function randomColor() {
    return 'rgb(' +
        random(0, 255) + ', ' +
        random(0, 255) + ', ' +
        random(0, 255) + ')';
}

class Game {
    constructor() {
        this.balls = []
        for (let i = 0; i < 40; i++) {
            let ball = new Ball(random(200, 600), random(200, 400), random(-10, 10), random(-10, 10), random(10, 20), randomColor())
            this.balls.push(ball)
        }
    }
    start() {
        setInterval(() => {
            // 为了形成拖尾效果
            context.fillStyle = `rgba(0,0,0,.3)`
            context.fillRect(0, 0, 800, 600)

            this.balls.forEach(ball => {
                // 移动小球
                ball.move()
                // 把小球再画出来
                ball.draw(context)

                // 判断碰撞修改每个小球的颜色
                this.balls.forEach(other => {
                    // 如果 两个小球是同一个，就不判断
                    if (other === ball) return
                    if (ball.isCollision(other)) {
                        ball.color = other.color = randomColor()
                    }
                })
            })
        }, 30);

    }
}


// 要得到一支笔，才能画东西
let cvs = document.getElementById('cvs')
let context = cvs.getContext('2d')
let g = new Game()
g.start()